package com.boot.security.server.service.impl.mffl.MfflUserlong;

import net.sf.json.JSONObject;
import com.boot.security.server.dao.PermissionDao;
import com.boot.security.server.dao.UserDao;
import com.boot.security.server.dao.mffl.MfflUserDao;
import com.boot.security.server.dto.LoginUser;
import com.boot.security.server.dto.Token;
import com.boot.security.server.dto.UserDto;
import com.boot.security.server.filter.TokenFilter;
import com.boot.security.server.model.SysUser;
import com.boot.security.server.model.mffl.MfflUser;
import com.boot.security.server.model.mffl.Vo.LoginReturnVo;
import com.boot.security.server.service.RoleService;
import com.boot.security.server.service.TokenService;
import com.boot.security.server.service.UserService;
import com.boot.security.server.utils.UserUtil;
import com.boot.security.server.utils.mffl.ProjectUtil;
import com.boot.security.server.utils.mffl.ReturnBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.apache.http.client.HttpClient;
import com.boot.security.server.controller.mffl.Mfflpublic;

import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;

import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 用户登录注册
 */
@Service
public class UserlongService {

    //图片路径
    @Value("${files.path}")
    private String imageth;

    //用户附属表
    @Autowired
    private MfflUserDao mfflUserDao;

    //token
    @Autowired
    private TokenService tokenService;

    //权限表
    @Autowired
    private PermissionDao permissionDao;

    //系统表
    @Autowired
    private UserDao userDao;

    //权限
    @Autowired
    private RoleService roleService;

    //系统封装service
    @Autowired
    private UserService userService;

    //图片上传
    @Autowired
    Mfflpublic mfflpublic;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    //微信登录
    public ReturnBean<LoginReturnVo> wechatlogin(String openid, String access_token) {
        //验证微信
        Map<String, String> map = verifyWechatLogin(openid, access_token);
        if (map.size() == 0) {
            ReturnBean returnBean = new ReturnBean();
            returnBean.setReturnBean("132");
            return returnBean;
        }


        ReturnBean returnBean = new ReturnBean();
        //查询用户,未注册与未绑定手机号的用户不允许登录
        MfflUser MfflUser = mfflUserDao.getByoPenid(openid);
        if (MfflUser == null) {
            returnBean.setReturnBean("130");
            return returnBean;
        } else {
            return getUserLoginToken(MfflUser.getUserid());
        }
    }


    //微信与手机号绑定
    public ReturnBean<LoginReturnVo> openidAndphoneBind(String openid, String phone, String access_token) {
        //获取用户信息
        Map<String, String> map = verifyWechatLogin(openid, access_token);
        if (map.size() == 0) {
            ReturnBean returnBean = new ReturnBean();
            returnBean.setReturnBean("132");
            return returnBean;
        }

        ReturnBean returnBean = new ReturnBean();
        //当前手机号是否已经注册过
        MfflUser PhoneUser = mfflUserDao.getByPhoneUser(phone);
        if (PhoneUser == null) {
            //新增,创建用户信息
            String password = "123456";
            String username = getStringRandom(5);
            Date date = new Date();
            UserDto userDto = new UserDto();
            List<Long> dto = new ArrayList<Long>();
            dto.add(roleService.getrole("client").getId());
            userDto.setRoleIds(dto);
            userDto.setUsername(phone);
            userDto.setPassword(password);
            userDto.setNickname(map.get("nickname"));

            //保存微信头像到本地
            String headimgurl = "";
            try {
                headimgurl = avatarUrl(map.get("headimgurl"));
            } catch (Exception e) {
                e.printStackTrace();
                returnBean.setReturnBean("105");
                return returnBean;
            }

            userDto.setHeadImgUrl(headimgurl);
            userDto.setPhone(phone);
            userDto.setSex(1);
            SysUser sysUser = userService.saveUser(userDto);

            MfflUser mfflUser = new MfflUser();
            mfflUser.setUserid(sysUser.getId().intValue());
            mfflUser.setRealname("");
            mfflUser.setIdnumber("");
            mfflUser.setOpenid(map.get("openid"));  //设置openid
            mfflUser.setUnionid(map.get("unionid"));//设置unionid
            mfflUser.setAreaCode("");
            mfflUser.setRegisterMethod("微信");
            mfflUser.setAreaName("");
            mfflUser.setComid(0);
            mfflUser.setThirdlevel("");
            mfflUser.setLevel(0);
            mfflUser.setStartWorkTime(date);
            mfflUser.setWorkCode("");
            mfflUser.setLawfirm("");
            mfflUser.setField("");
            mfflUser.setServerNumber(0);
            mfflUser.setRating("100");
            mfflUser.setWorkBootImage("");
            mfflUser.setEducation("");
            mfflUser.setContent("");
            mfflUser.setIntegral(0);
            mfflUser.setGradeIntegral("");
            mfflUser.setSearchLike("");
            mfflUser.setCreateTime(date);
            mfflUser.setUpdateTime(date);
            mfflUser.setIdentity(1);//身份标识(0用户,1律师)
            mfflUser.setDeleteTime(date);
            mfflUser.setDeleteState(1);
            mfflUser.setLawyerInspect(1);
            mfflUser.setMoney(ProjectUtil.addition(0.0, 0.0));
            mfflUser.setIdnumberImage("");
            mfflUser.setSecondusername(ProjectUtil.getRandomString(12));//唯一用户名
            mfflUserDao.save(mfflUser);
            return getUserLoginToken(userDto.getId().intValue());
        } else {
            //注册过
            if ((StringUtils.isEmpty(PhoneUser.getOpenid()) || StringUtils.isEmpty(PhoneUser.getUnionid())) && PhoneUser.getIdentity() == 0) {
                //当前openid更新到对应数据上
                MfflUser mfflUser = new MfflUser();
                mfflUser.setId(PhoneUser.getId());
                mfflUser.setOpenid(map.get("openid"));
                mfflUser.setUnionid(map.get("unionid"));
                Date date = new Date();
                mfflUser.setUpdateTime(date);
                mfflUserDao.update(mfflUser);
                return getUserLoginToken(PhoneUser.getUserid().intValue());
            } else {
                //提示已绑定过
                returnBean.setReturnBean("131");
                return returnBean;
            }
        }
    }


    //微信与手机号解除绑定
    public ReturnBean openidAndphoneUnbind(HttpServletRequest request, String openid, String access_token) {
        Map<String, String> map = verifyWechatLogin(openid, access_token);
        if (map.size() == 0) {
            ReturnBean returnBean = new ReturnBean();
            returnBean.setReturnBean("132");
            return returnBean;
        }

        //获取当前用户
        SysUser sUser = UserUtil.getLoginUser();
        //查询用户状态
        MfflUser User = mfflUserDao.getByUserId(sUser.getId());

        if (User == null) {
            return new ReturnBean("201", "当前用户不存在");
        }

        if (StringUtils.isEmpty(User.getOpenid())) {
            return new ReturnBean("201", "当前用户未绑定微信号");
        }

        //清空被解绑手机号openid
        MfflUser updateUser = new MfflUser();
        updateUser.setId(User.getId());
        updateUser.setOpenid("");//清空openid
        updateUser.setUnionid("");//清空Unionid
        Date date = new Date();
        updateUser.setUpdateTime(date);
        mfflUserDao.update(updateUser);
        return new ReturnBean();
    }


    //传入用户id返回token
    public ReturnBean<LoginReturnVo> getUserLoginToken(Integer id) {
        //获取用户信息
        MfflUser MfflUser = mfflUserDao.getmffluser(id);
        SysUser sysuser = userDao.getById(MfflUser.getUserid().longValue());

        //配置登录用户信息
        LoginUser loginUser = new LoginUser();
        loginUser.setPermissions(permissionDao.listByUserId(sysuser.getId()));
        loginUser.setId(sysuser.getId());
        loginUser.setUsername(sysuser.getUsername());
        loginUser.setPassword("$10$.QfHB7vQwZ/DGiYo.cckJeRCpk5.bMnFCrG6DmtCCMwu0vnib.RrG");
        loginUser.setNickname(sysuser.getNickname());
        loginUser.setHeadImgUrl(sysuser.getHeadImgUrl());
        loginUser.setCreateTime(sysuser.getCreateTime());
        loginUser.setUpdateTime(sysuser.getUpdateTime());

        //获取token
        Token token = tokenService.saveToken(loginUser);

        //返回前端数据
        LoginReturnVo loginReturnVo = new LoginReturnVo();
        loginReturnVo.setToken(token.getToken());
        loginReturnVo.setUserInfo(mfflUserDao.getUserInfoSimple(sysuser.getId().intValue()));
        loginReturnVo.setSys_id(sysuser.getId());
        loginReturnVo.setNickanme(sysuser.getNickname());
        loginReturnVo.setPhone(sysuser.getPhone());
        loginReturnVo.setLoginTime(token.getLoginTime());
        loginReturnVo.setUsername(sysuser.getUsername());
        loginReturnVo.setEmail(sysuser.getEmail());
        loginReturnVo.setIdentity(MfflUser.getIdentity());
        loginReturnVo.setIdnumber(MfflUser.getIdnumber());
        loginReturnVo.setHeadImgUrl(MfflUser.getHeadImgUrl());
        loginReturnVo.setRealname(MfflUser.getRealname());
        loginReturnVo.setRegisterMethod(MfflUser.getRegisterMethod());
        ReturnBean returnBean = new ReturnBean();
        returnBean.setDatas(loginReturnVo);
        return returnBean;
    }


    //生成随机用户名，数字和字母组成,
    public static String getStringRandom(int length) {
        String name = "mffl";
        for (int i = 0; i < length; i++) {
            name += String.valueOf((int) (1 + Math.random() * 10));
        }
        return name;
    }

    //删除token
    public boolean deleteToken(HttpServletRequest request) {
        String token = TokenFilter.getToken(request);
        return tokenService.deleteToken(token);
    }


    //获取微信用户信息
    public Map<String, String> verifyWechatLogin(String openid, String access_token) {
        //获取用户信息
        String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "" + "&openid=" + openid + "";
        JSONObject jsonObject = doGetJson(infoUrl);
        HashMap<String, String> map = new HashMap<>();
        if (jsonObject.get("openid") != null) {
            map.put("openid", jsonObject.get("openid").toString());
            map.put("nickname", jsonObject.get("nickname").toString());
            map.put("sex", jsonObject.get("sex").toString());
            map.put("language", jsonObject.get("language").toString());
            map.put("city", jsonObject.get("city").toString());
            map.put("province", jsonObject.get("province").toString());
            map.put("country", jsonObject.get("country").toString());
            map.put("headimgurl", jsonObject.get("headimgurl").toString());
            map.put("privilege", jsonObject.get("privilege").toString());
            map.put("unionid", jsonObject.get("unionid").toString());
        }
        return map;
    }


    //get请求json
    public JSONObject doGetJson(String url) {
        JSONObject jsonObject = null;
        HttpClient httpclient = HttpClients.createDefault();
        HttpGet httpget = new HttpGet(url);
        try {
            HttpResponse httpresponse = httpclient.execute(httpget);
            HttpEntity entity = httpresponse.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity, "UTF-8");
                jsonObject = JSONObject.fromObject(result);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpget.releaseConnection();
        }
        return jsonObject;
    }


    //下载微信头像头像
    public String avatarUrl(String imageUrl) throws IOException {
        //拆分路径拼接https
        imageUrl = "https:" + imageUrl.split(":")[1];

        URL url = new URL(imageUrl);
        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
        // 得到URL的输入流
        InputStream input = con.getInputStream();
        // 设置数据缓冲
        byte[] bs = new byte[1024 * 2];
        // 读取到的数据长度
        int len = 0;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
        String format = simpleDateFormat.format(new Date());

        String imagename = ProjectUtil.getRandom(32) + ".png";
        String dbpath = format + "/" + imagename;
        String imagepath = imageth + "/" + dbpath;

        //创建文件夹
        File file = new File(imageth + "/" + format);
        if (!file.exists()) {
            file.mkdirs();
        }

        // 输出的文件流保存图片至本地
        OutputStream os = new FileOutputStream(new File(imagepath));
        while ((len = input.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
        os.close();
        input.close();
        return "/" + dbpath;
    }

    /**
     * 修改密码
     *
     * @param newpassword        新密码
     * @param confirmnewpassword 确认新密码
     * @param userphone          用户手机号
     * @param code               手机验证码
     * @return
     */
    public ReturnBean ChangePassword(String newpassword, String confirmnewpassword, String userphone, String code) {
        ReturnBean returnBean = new ReturnBean();

     /*   SysUser sysUser = UserUtil.getLoginUser();
        SysUser byId = userDao.getById(sysUser.getId());*/

        MfflUser byPhone = mfflUserDao.getByPhone(userphone);
        SysUser byId = userDao.getById(byPhone.getUserid().longValue());

        if (!byId.getPhone().equals(userphone)) {
            return new ReturnBean("201", "提交手机号，与用户手机号不符");
        }
        try {
            userDao.changePassword(byId.getId(), passwordEncoder.encode(confirmnewpassword));
        } catch (Exception e) {
            returnBean.setReturnBean("105");
            e.printStackTrace();
        } finally {
            return returnBean;
        }
    }
}
